﻿using SmartWMS.Common.Extensions;
using SmartWMS.Common.ResponseOutput;
using SmartWMS.Common.Signalr;
using SmartWMS.Domain.BasicsDatum;
using SmartWMS.Domain.BusinessManage;
using SmartWMS.Domain.SystemSet;
using SmartWMS.Domain.WarehouseManage;
using SmartWMS.EntityFramework;
using SmartWMS.Server.Repository;
using SmartWMS.Server.WarehouseManage.CheckServer.Dto;
using SmartWMS.Server.WarehouseManage.InventoryLedgerServer.Dto;
using SmartWMS.Server.WarehouseManage.OutWarehouseServer.Dto;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmartWMS.Common;

namespace SmartWMS.Server.WarehouseManage.OutWarehouseServer
{
    /// <summary>
    /// 出库管理
    /// </summary>
    public class OutWarehouseServers : IOutWarehouseServers
    {
        private readonly IRepository<OutWarehouse> _outWarehouse;
        private readonly IRepository<OutWarehouseDetail> _outWarehouseDetail;
        private readonly IRepository<Product> _product;
        private readonly IRepository<Warehouse> _warehouse;
        private readonly IRepository<Location> _location;
        private readonly IRepository<MessageCenter> _messageCenter;
        private readonly SmartWMSContext _smartWMSContext;
        private readonly IRepository<SalesManagement> _salesManagement;
        private readonly IRepository<CustomContact> _customContact;
        SmartWMS.Common.ChatHub Hub =new SmartWMS.Common.ChatHub();

        public OutWarehouseServers(IRepository<OutWarehouse> outWarehouse, IRepository<OutWarehouseDetail> outWarehouseDetail, IRepository<Warehouse> warehouse, IRepository<Location> location, IRepository<Product> product, SmartWMSContext smartWMSContext, IRepository<MessageCenter> messageCenter, IRepository<SalesManagement> salesManagement, IRepository<CustomContact> customContact)
        {
            _outWarehouse = outWarehouse;
            _outWarehouseDetail = outWarehouseDetail;
            _product = product;
            _warehouse = warehouse;
            _location = location;
            _smartWMSContext = smartWMSContext;
            _messageCenter = messageCenter;
            _salesManagement = salesManagement;
            _customContact = customContact;
        }

        /// <summary>
        /// 出库管理列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<List<OutWarehouseDtoPuls>>> GetOutWarehouseDtoPes(OutWarehouseDtoPage dto)
        {
            try
            {
                //出库表
                var plist = await _outWarehouse.GetAllListAsync();
                //出库明细表
                var outWarehouselist = await _outWarehouseDetail.GetAllListAsync();
                //产品表
                var productlist = await _product.GetAllListAsync();
                //仓库表
                var warehouselist = await _warehouse.GetAllListAsync();
                //库位表
                var locationlist = await _location.GetAllListAsync();
                var list = (from a in plist
                            join b in outWarehouselist on a.OutWarehouseCode equals b.OutWarehouseCode
                            join c in productlist on b.ProductCode equals c.ProductCode
                            join d in warehouselist on b.WarehouseId equals d.Id
                            join e in locationlist on b.Location equals e.Id
                            select new OutWarehouseDtoPuls
                            {
                                Id = b.Id,
                                OutWarehouseCode = a.OutWarehouseCode,
                                ProductCode = b.ProductCode,
                                ProductName = c.ProductName,
                                Batch = b.Batch,
                                Unit = c.Unit,
                                OutWarehouseNumber = b.OutWarehouseNumber,
                                Name = d.Name,
                                LocationName = e.LocationName,
                                OutWarehouseType = a.OutWarehouseType,
                                CustomerName = a.CustomerName,
                                Creator = a.Creator,
                                Reviewer = a.Reviewer,
                                Audittime = a.Audittime,
                                State = a.State
                            }).ToList();

                if (!string.IsNullOrEmpty(dto.OutWarehouseCode))
                {
                    list = list.Where(x => x.OutWarehouseCode.Contains(dto.OutWarehouseCode)).ToList();
                }
                if (dto.OutWarehouseType > 0)
                {
                    list = list.Where(x => x.OutWarehouseType == dto.OutWarehouseType).ToList();
                }
                if (dto.State > 0)
                {
                    list = list.Where(x => x.State == dto.State).ToList();
                }
                int totalCount = list.Count();
                int pageCount = (int)Math.Ceiling((double)totalCount / dto.Size);
                list = list.Skip((dto.Page - 1) * dto.Size).Take(dto.Size).ToList();
                return list != null ? Response<List<OutWarehouseDtoPuls>>.Ok(list, totalCount, pageCount) : Response<List<OutWarehouseDtoPuls>>.Fail(new List<OutWarehouseDtoPuls>());
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 查看
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<OutWarehouseDtoPes>> GetViewOutWarehouse(OutWarehouseDtoPes dto)
        {
            try
            {
                var plist = _outWarehouse.GetListQuery().FirstOrDefault(t => t.OutWarehouseCode == dto.OutWarehouseCode);
                var list = plist.MapTo<OutWarehouseDtoPes>();
                var outWarehouselist = await _outWarehouseDetail.GetAllListAsync();
                var productlist = await _product.GetAllListAsync();
                var warehouselist = await _warehouse.GetAllListAsync();
                var locationlist = await _location.GetAllListAsync();
                list.OutWarehouseDetailDtoPas = (
                            from b in outWarehouselist
                            join c in productlist on b.ProductCode equals c.ProductCode
                            join d in warehouselist on b.WarehouseId equals d.Id
                            join e in locationlist on b.Location equals e.Id
                            where b.OutWarehouseCode == dto.OutWarehouseCode
                            select new OutWarehouseDetailDtoPas
                            {
                                Id = b.Id,
                                OutWarehouseCode = b.OutWarehouseCode,
                                ProductCode = b.ProductCode,
                                ProductName = c.ProductName,
                                Batch = b.Batch,
                                OutWarehouseNumber = b.OutWarehouseNumber,
                                Price = b.Price,
                                WarehouseId = b.WarehouseId,
                                Name = d.Name,
                                Location = b.Location,
                                LocationName = e.LocationName,
                                Specs = c.Specs

                            }).ToList();
                return list != null ? Response<OutWarehouseDtoPes>.Ok(list) : Response<OutWarehouseDtoPes>.Fail(new OutWarehouseDtoPes());
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 审核出库状态
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<bool>> UpdateStateOutWare(OutWarehouseDtoPes dto)
        {

            try
            {
                //出库表
                var list = _outWarehouse.GetListQuery().FirstOrDefault(t => t.OutWarehouseCode == dto.OutWarehouseCode);
                //出库明细表
                var plist = _outWarehouseDetail.GetListQuery().Where(t => t.OutWarehouseCode == dto.OutWarehouseCode).ToList();
                var slist = new List<Product>();

                var solist = new List<MessageCenter>();
                var olist = new MessageCenter();
                //循环明细表修改库存 并判断库存是否预警
                foreach (var item in plist)
                {
                    var tlist = _product.GetListQuery().FirstOrDefault(t => t.ProductCode == item.ProductCode);
                    if (tlist.Inventory < item.OutWarehouseNumber)
                    {

                        olist.MsgTitle = "出库审核";
                        olist.MsgContent = "出库审核失败，库存不足";
                        olist.MsgType = "出库审核";
                        olist.MsgState = "未读";
                        olist.MsgTime = DateTime.Now.ToString();
                        var result = await _messageCenter.InsertAsync(olist);
                        return Response<bool>.Fail(false);
                    }
                    tlist.Inventory -= item.OutWarehouseNumber;
                    if (tlist.Inventory <= tlist.Floor)
                    {

                        olist.MsgTitle = "出库审核";
                        olist.MsgContent = $"出库审核失败，库存预警";
                        olist.MsgType = "出库审核";
                        olist.MsgState = "未读";
                        olist.MsgTime = DateTime.Now.ToString();
                        //var result = await _messageCenter.InsertAsync(olist);
                    }
                    else
                    {

                        olist.MsgTitle = "出库审核";
                        olist.MsgContent = "出库审核成功，库存减少";
                        olist.MsgType = "出库审核";
                        olist.MsgState = "未读";
                        olist.MsgTime = DateTime.Now.ToString();
                    }
                    slist.Add(tlist);
                    solist.Add(olist);
                }
                if (list != null)
                {


                    using (var tran = _smartWMSContext.Database.BeginTransaction())
                    {
                        try
                        {
                            list.State = dto.State;
                            list.Opinion = dto.Opinion;
                            list.Reviewer = dto.Reviewer;
                            list.Audittime = DateTime.Now;
                            var result = await _outWarehouse.UpdateAsync(list);
                            if (result > 0)
                            {
                                var result1 = await _product.UpdateRangeAsync(slist);
                                if (result1 > 0)
                                {

                                    var result2 = await _messageCenter.InsertAsync(solist);
                                    if (result2 > 0)
                                    {
                                        
                                        tran.Commit();
                                        return Response<bool>.Ok(true);
                                    }
                                    else
                                    {
                                        tran.Rollback();
                                        return Response<bool>.Fail(false);
                                    }

                                }
                                else
                                {
                                    tran.Rollback();
                                    return Response<bool>.Fail(false);
                                }
                            }
                            tran.Rollback();
                            return Response<bool>.Fail(false);
                        }


                        catch (Exception)
                        {
                            tran.Rollback();
                            throw;
                        }
                    }
                }
                return Response<bool>.Fail(false);

            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<bool>> DelOutWare(OutWarehouseDtoPes dto)
        {
            try
            {
                //查出出库表、出库明细表并删除
                var list = _outWarehouse.GetListQuery().FirstOrDefault(t => t.OutWarehouseCode == dto.OutWarehouseCode);
                var plist = await _outWarehouseDetail.GetAllListAsync();
                plist = plist.Where(t => t.OutWarehouseCode == dto.OutWarehouseCode).ToList();

                if (list != null)
                {
                    using (var tran = _smartWMSContext.Database.BeginTransaction())
                    {
                        try
                        {
                            var result = await _outWarehouse.DeleteByIdAsync(list);
                            if (result > 0)
                            {

                                if (plist != null)
                                {
                                    var i = await _outWarehouseDetail.DeleteAsync(plist);
                                    if (i > 0)
                                    {
                                        tran.Commit();
                                        return Response<bool>.Ok(true);
                                    }
                                    else
                                    {
                                        //回滚
                                        tran.Rollback();
                                        return Response<bool>.Fail(false);
                                    }
                                }
                                else
                                {
                                    //回滚
                                    tran.Rollback();
                                    return Response<bool>.Fail(false);
                                }
                            }
                            else
                            {
                                //回滚
                                tran.Rollback();
                                return Response<bool>.Fail(false);
                            }
                        }
                        catch (Exception)
                        {
                            //回滚
                            tran.Rollback();
                            throw;
                        }
                    }

                }
                else
                {
                    return Response<bool>.Fail(false);
                }
            }
            catch (Exception)
            {

                throw;
            }
        }


        /// <summary>
        /// 批量删除数据（）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<bool>> DeleteOutWare(List<OutWarehouseDtoPes> dto)
        {
            try
            {
                //查出出库表、出库明细表并删除
                var list = _outWarehouse.GetListQuery().Where(t => dto.Select(x => x.OutWarehouseCode).Contains(t.OutWarehouseCode)).ToList();
                var plist = _outWarehouseDetail.GetListQuery().Where(t => list.Select(x => x.OutWarehouseCode).Contains(t.OutWarehouseCode)).ToList();

                if (list != null)
                {
                    using (var tran = _smartWMSContext.Database.BeginTransaction())
                    {
                        try
                        {
                            var result = await _outWarehouse.DeleteAsync(list);
                            if (result > 0)
                            {
                                var i = await _outWarehouseDetail.DeleteAsync(plist);
                                if (i > 0)
                                {
                                    tran.Commit();
                                    return Response<bool>.Ok(true);
                                }
                                else
                                {
                                    //回滚
                                    tran.Rollback();
                                    return Response<bool>.Fail(false);
                                }
                            }
                            else
                            {
                                //回滚
                                tran.Rollback();
                                return Response<bool>.Fail(false);
                            }
                        }
                        catch (Exception)
                        {
                            //回滚
                            tran.Rollback();
                            throw;
                        }
                    }
                }

                else
                {
                    return Response<bool>.Fail(false);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 添加出库出库明细
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AddOutWare(OutWarehouseDtoPes dto)
        {
            try
            {
                dto.CreateTime = DateTime.Now;
                dto.State = 1;
                //出库表
                var OutWarehouseDetaillist = dto.OutWarehouseDetailDtoPas;
                //出库明细
                var CheckDetailsLists = OutWarehouseDetaillist.Select(item => new OutWarehouseDetail
                {
                    OutWarehouseCode = dto.OutWarehouseCode,
                    ProductCode = item.ProductCode,
                    Batch = item.Batch,
                    Price = item.Price,
                    OutWarehouseNumber = item.OutWarehouseNumber,
                    WarehouseId = item.DefaultWarehouseId,
                    Location = item.DefaultLocationId,
                }).ToList();
                using (var tran = _smartWMSContext.Database.BeginTransaction())
                {
                    try
                    {
                        var result = await _outWarehouse.InsertAsync(dto.MapTo<OutWarehouse>());
                        if (result > 0)
                        {
                            var i = await _outWarehouseDetail.InsertAsync(CheckDetailsLists);
                            if (i > 0)
                            {
                                //提交
                                tran.Commit();
                                return Response<bool>.Ok(true);
                            }
                            else
                            {
                                //回滚
                                tran.Rollback();
                                return Response<bool>.Fail(false);
                            }

                        }
                        else
                        {
                            //回滚
                            tran.Rollback();
                            return Response<bool>.Fail(false);
                        }
                    }
                    catch (Exception)
                    {
                        tran.Rollback();
                        throw;
                    }
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 联想查询
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<List<SalesDtoPas>>> Getassociation(OutWarehouseDtoPage dto)
        {
            //销售管理表
            var list = await _salesManagement.GetAllListAsync();
            
            list = list.Where(t => t.DocumentType == dto.OutWarehouseType.ToString()).ToList();
            //客户联系人表
            var plist = await _customContact.GetAllListAsync();
            //联想查询
            var slist = (from a in list
                         join b in plist on a.ClientCode equals b.CustomrCode
                         orderby a.SalesCode
                         group new { a, b } by a.ClientCode into grouped
                         select new SalesDtoPas
                         {
                             SalesCode = grouped.First().a.SalesCode,
                             ClientCode = grouped.Key,
                             ClientName = grouped.First().a.ClientName,
                             Phone = grouped.First().b.Phone,
                             Contacts = grouped.First().b.Contacts
                         }).ToList();

            return slist != null ? Response<List<SalesDtoPas>>.Ok(slist) : Response<List<SalesDtoPas>>.Fail(new List<SalesDtoPas>());
        }

        /// <summary>
        /// 反填数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public OutWarehouseDtoPes ReckOutWare(OutWarehouseDtoPage dto)
        {
            try
            {
                var list = _outWarehouse.GetListQuery().FirstOrDefault(t => t.OutWarehouseCode == dto.OutWarehouseCode);
                var slist = list.MapTo<OutWarehouseDtoPes>();
                var plist = _outWarehouseDetail.GetListQuery().Where(t => t.OutWarehouseCode == dto.OutWarehouseCode).ToList();
                var productlist = _product.GetListQuery().ToList();
                slist.OutWarehouseDetailDtoPas = (from a in plist
                                   join b in productlist on a.ProductCode equals b.ProductCode
                                   select new OutWarehouseDetailDtoPas
                                   {
                                       Id = a.Id,
                                       OutWarehouseCode = a.OutWarehouseCode,
                                       ProductCode = a.ProductCode,
                                       ProductName = b.ProductName,
                                       Batch = a.Batch,
                                       OutWarehouseNumber =     a.OutWarehouseNumber,
                                       Price = a.Price,
                                       Specs=b.Specs,
                                       WarehouseId = a.WarehouseId,
                                       Location = a.Location
                                   }).ToList();
                                 
                return slist;
            }
            catch (Exception)
            {

                throw;
            }
        }


        /// <summary>
        /// 批量修改数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<Response<bool>> UpdateOutWare(OutWarehouseDtoPes dto)
        {
            var productlist = dto.OutWarehouseDetailDtoPas;
            var outwareLists = productlist.Select(item => new OutWarehouseDetail
            {
                Id = item.Id,
                OutWarehouseCode = item.OutWarehouseCode,
                ProductCode = item.ProductCode,
                Batch = item.Batch,
                Price = item.Price,
                OutWarehouseNumber = item.OutWarehouseNumber,
                WarehouseId = item.WarehouseId,
                Location = item.Location,
                
            }).ToList();
            using (var tran = _smartWMSContext.Database.BeginTransaction())
            {
                try
                {
                    var result = await _outWarehouse.UpdateAsync(dto.MapTo<OutWarehouse>());
                    if (result > 0)
                    {
                        //var tlist=  _outWarehouseDetail.GetListQuery().Where(t=>t.OutWarehouseCode==dto.OutWarehouseCode).ToList();
                        //var ist = await _outWarehouseDetail.DeleteAsync(tlist);
                        //if (ist > 0)
                        //{
                            var i = await _outWarehouseDetail.UpdateRangeAsync(outwareLists);
                            if (i > 0)
                            {
                                //提交
                                tran.Commit();
                                return Response<bool>.Ok(true);
                            }
                            else
                            {
                                //回滚
                                tran.Rollback();
                                return Response<bool>.Fail(false);
                            }

                        //}else
                        //{
                        //    //回滚
                        //    tran.Rollback();
                        //    return Response<bool>.Fail(false);
                        //}     

                    }
                    else
                    {
                        //回滚
                        tran.Rollback();
                        return Response<bool>.Fail(false);
                    }
                }
                catch (Exception)
                {
                    tran.Rollback();
                    throw;
                }
            }
        }

    }
}
